#pragma once

#include <fstream>

#include"common.hpp"
#include "Http_agre.hpp"

class Business
{
    typedef function<void(const string &, const HttpRequest &, HttpResponse &)> service_t;

    // 构建表示资源不存在的页面
    void ConstructNotFoundPage(const HttpRequest &requ, HttpResponse &resp)
    {
        // 设置HTTP版本
        resp.SetVersion(requ.version());

        // 设置状态码和状态码描述
        resp.SetStatusCode(404);
        resp.SetStatusCodeDescription("Not Found");

        // 打开表示“用户请求的资源不存在”的网页文件
        ifstream in(defalut_notFound_page_path, ios::in);
        if (!in.is_open())
        {
            LOG(LogLevel::WARNING) << defalut_notFound_page_path << "打开失败";
        }

        // 读取网页文件
        string notFound_page;
        string line;
        while (getline(in, line))
        {
            notFound_page += (line + "\r\n");
        }
        // 设置响应报头
        resp["Content-Type"] = "html";
        resp["Content-Lenth"] = to_string(notFound_page.size());

        // 设置响应正文
        resp.SetBody(notFound_page);

        in.close();
    }

    void StaticServices(const HttpRequest &requ, HttpResponse &resp) // 处理静态服务
    {
        LOG(LogLevel::DEBUG) << "开始静态服务";

        // 添加web根目录
        string url = defalut_web_root + requ.Url();

        if (url.back() == '/') // 如果用户访问资源目录，就返回该目录的首页
        {
            // 添加首页文件名
            url += defalut_homepage_file;
        }

        // 设置HTTP版本
        resp.SetVersion(requ.version());

        // 打开资源文件
        ifstream ifs(url, ios::in);
        if (!ifs.is_open()) // 打开失败
        {
            // 构建资源不存在的页面
            ConstructNotFoundPage(requ, resp);
        }
        else // 打开成功,返回用户请求的资源
        {
            // 设置状态码和状态码描述
            resp.SetStatusCode(200);
            resp.SetStatusCodeDescription("OK");

            // 读取资源目录对应的首页文件
            string page;
            string line;
            while (getline(ifs, line))
            {
                page += (line + "\r\n");
            }
            // 设置响应报头
            resp["Content-Type"] = "html";
            resp["Content-Lenth"] = to_string(page.size());

            // 设置响应正文
            resp.SetBody(page);

            ifs.close();
        }
    }
    void DynamicServices(const HttpRequest &requ, HttpResponse &resp) // 处理动态服务
    {
        LOG(LogLevel::DEBUG) << "开始动态服务";

        // 添加web根目录
        string url = defalut_web_root + requ.Url();

        string key;
        string args;
        if (requ.RequMethod() == "GET" || requ.RequMethod() == "get")
        {
            // 解析URL取出动态服务的key和参数
            int key_end = url.rfind(defalut_URL_path_options_sep);
            int key_start = url.rfind("/",key_end);
            key = url.substr(key_start + 1, key_end-(key_start+1));

            args = url.substr(key_end + 1);
        }
        else if (requ.RequMethod() == "POST" || requ.RequMethod() == "post")
        {
            // 解析URL取出动态服务的key和参数
            int key_start = url.rfind("/");
            key = url.substr(key_start + 1);
            args = requ.Body();
        }

        // 判断服务是否存在
        if (_loop.find(key) == _loop.end()) // 如果不存在
        {
            LOG(LogLevel::WARNING) << "用户提交的动态服务: " << key << "不存在";

            // 构建资源不存在的页面
            ConstructNotFoundPage(requ, resp);
            return;
        }
        else // 如果存在
        {
            // 调用对应的动态服务函数，在服务器中进行对应操作
            _loop[key](args, requ, resp);
        }
    }
    void HandleCookie(const string& v)
    {
        string key;
        string val;

        Partition(v,"=",key,val);

        //处理session_id
        stringstream ss(val);
        uint64_t sid;
        ss>>sid;

        LOG(LogLevel::DEBUG) << "处理session_id: "<<sid;

        //设置为登录状态
        gsession_table.SetisLogin(sid,true);
    }
public:
    void AddService(const string &key, service_t val)
    {
        _loop.insert({key, val});
    }
    void Dispose(const HttpRequest &requ, HttpResponse &resp)
    {
        LOG(LogLevel::DEBUG) << "进入Business: Dispose";

        //处理cookie
        if(requ.isMasthead("Cookie"))
        {
            HandleCookie(requ["Cookie"]);
        }

        // 判断用户请求的服务类型
        if (requ.RequMethod() == "GET" || requ.RequMethod() == "get")
        {
            string url = requ.Url();

            // 如果有选项，那就是动态服务
            if (url.rfind(defalut_URL_path_options_sep) != string::npos)
            {
                DynamicServices(requ, resp);
            }
            else // 否则就是静态服务
            {
                StaticServices(requ, resp);
            }
        }
        else if (requ.RequMethod() == "POST" || requ.RequMethod() == "post")
        {
            if (requ.Body().empty()) // 如果请求正文为空
            {
                // 静态服务
                StaticServices(requ, resp);
            }
            else
            {
                // 动态服务
                DynamicServices(requ, resp);
            }
        }
        else
        {
        }
    }

private:
    unordered_map<string, service_t> _loop;//负责动态服务的路由
};